import com.asnike.P.bejeweled.*;
import com.greensock.TweenMax;

import flash.events.*;

private function checkSameJewelsOneLine():void{
	checkSameJewelsHorizonLine();
	checkSameJewelsVerticalLine();
	if( haveSameJewels() ){
		removeAllFromSelectedJewels();
		removeSameJewels();
		fillBlanks();
	}else{
		returnSelectedJewels();
	}
//	debugMap();
}
private function checkSameJewelsHorizonLine():void{
	var i:int, j:int, k:int, l:int, map:Array, check:int, sameStartIndex:int;
	
	map = getMap();
	for( i = 0, j = map.length ; i < j ; ++i ){
		for( k = 0, l = map[i].length - 1 ; k < l ; ++k ){
			if( isSameWithNextJewel( map[i], k ) ){
				++check;
			}else if( check < 2 ){
				check = 0;
			}
			if( isStartSame( check ) ){
				sameStartIndex = k;
			}
			if( isSameThreeMore( check ) && isLineEnd( k, l ) || isSameThreeMore( check ) && isNotSameWithNextJewel( map[i], k + 1 ) ){
				setWillBeRemoveSameJewelsHorizon( map[i], sameStartIndex, sameStartIndex + check );
				check = 0;
			}else if( isLineEnd( k, l ) ){
				check = 0;
			}
		}
	}
}
private function isSameWithNextJewel( $map:Array, $index:int ):Boolean{
	return getJewelType( $map[$index] ) === getJewelType( $map[$index + 1] )
}
private function getJewelType( $target:Jewel ):int{
	if( $target === null ){
		return GameModel.JEWEL_EMPTY;
	}
	return $target.getType();
}
private function isNotSameWithNextJewel( $map:Array, $index:int ):Boolean{
	return !isSameWithNextJewel( $map, $index );
}
private function isStartSame( $value:int ):Boolean{
	return $value === 1;
}
private function isSameThreeMore( $value:int ):Boolean{
	return $value >= 2;
}
private function isLineEnd( $current:int, $next:int ):Boolean{
	return $current === $next - 1;
}
private function setWillBeRemoveSameJewelsHorizon( $map:Array, $startIndex:int, $endIndex:int ):void{
	var i:int, j:int;
	
	for( i = $startIndex, j = $endIndex + 1 ; i < j ; ++i ){
		setWillBeRemove( $map[i] );
	}
}
private function setWillBeRemove( $target:Jewel ):void{
	if( $target ){
		$target.setWillBeRemove();
	}
}
private function checkSameJewelsVerticalLine():void{
	var i:int, j:int, k:int, l:int, map:Array, check:int, sameStartIndex:int;
	
	map = getMap();
	for( i = 0, j = map.length ; i < j ; ++i ){
		for( k = 0, l = map[i].length - 1 ; k < l ; ++k ){
			if( isSameWithDownJewel( map, k, i ) ){
				++check;
			}else if( check < 2 ){
				check = 0;
			}
			if( isStartSame( check ) ){
				sameStartIndex = k;
			}
			if( isSameThreeMore( check ) && isLineEnd( k, l ) || isSameThreeMore( check ) && isNotSameWithDownJewel( map, k + 1, i ) ){
				setWillBeRemoveSameJewelsVertical( map, i, sameStartIndex, sameStartIndex + check );
				check = 0;
			}else if( isLineEnd( k, l ) ){
				check = 0;
			}
		}
	}
}
private function isSameWithDownJewel( $map:Array, $indexX:int, $indexY:int ):Boolean{
	return getJewelType( $map[$indexX][$indexY] ) === getJewelType( $map[$indexX + 1][$indexY] );
}
private function isNotSameWithDownJewel( $map:Array, $indexX:int, $indexY:int ):Boolean{
	return !isSameWithDownJewel( $map, $indexX, $indexY );
}
private function setWillBeRemoveSameJewelsVertical( $map:Array, $col:int, $startIndex:int, $endIndex:int ):void{
	var i:int, j:int;
	
	for( i = $startIndex, j = $endIndex + 1 ; i < j ; ++i ){
		setWillBeRemove( $map[i][$col] );
	}
}
private function haveSameJewels():Boolean{
	var i:int, j:int, k:int, l:int, map:Array;
	
	map = getMap();
	for( i = 0, j = map.length ; i < j ; ++i ){
		for( k = 0, l = map[i].length ; k < l ; ++k ){
			if( willBeRemove( map[i][k] ) ){
				return true;
			}
		}
	}
	return false;
}
private function removeSameJewels():void{
	var i:int, j:int, k:int, l:int, map:Array;
	
	map = getMap();
	for( i = 0, j = map.length ; i < j ; ++i ){
		for( k = 0, l = map[i].length ; k < l ; ++k ){
			if( willBeRemove( map[i][k] ) ){
				removeJewel( map[i][k] );
				map[i][k] = null;
			}
		}
	}
}
private function willBeRemove( $target:Jewel ):Boolean{
	if( $target ){
		return $target.getWillBeRemove();
	}
	return false;
}
private function removeJewel( $target:Jewel ):void{
	if( $target ){
		$target.removeEventListener( MouseEvent.CLICK, JEWEL_CLICK );
		_view.removeJewel( $target );
	}
}